# -*- coding: utf-8 -*-
"""
系统配置管理数据模型

按照模块文档-09-系统管理.md的2.2节规范实现
支持三大类配置：基础配置、业务配置、系统参数
"""

from datetime import datetime
from typing import Optional, Dict, Any, List
from enum import Enum

from sqlalchemy import Column, Integer, String, Text, DateTime, Boolean, JSON, Enum as SQLEnum
from sqlalchemy.orm import relationship

from .base import BaseModel


class ConfigCategory(str, Enum):
    """配置分类枚举"""
    BASIC = "basic"        # 基础配置：系统基本信息、数据库配置
    BUSINESS = "business"  # 业务配置：客户管理、产品管理、财务配置
    SYSTEM = "system"      # 系统参数：安全设置、性能设置、通知设置


class ConfigType(str, Enum):
    """配置值类型枚举"""
    STRING = "string"      # 字符串类型
    NUMBER = "number"      # 数字类型
    BOOLEAN = "boolean"    # 布尔类型
    JSON = "json"          # JSON对象类型
    FILE = "file"          # 文件路径类型
    PASSWORD = "password"  # 密码类型（加密存储）


class ConfigScope(str, Enum):
    """配置生效范围枚举"""
    GLOBAL = "global"      # 全局配置
    MODULE = "module"      # 模块级配置
    USER = "user"          # 用户级配置


class SystemConfig(BaseModel):
    """
    系统配置模型
    
    存储系统的各种配置信息，支持分类管理、类型验证、范围控制
    """
    __tablename__ = "system_configs"

    # 基础字段
    config_key = Column(String(100), unique=True, nullable=False, index=True, comment="配置键")
    config_value = Column(Text, comment="配置值")
    config_category = Column(SQLEnum(ConfigCategory), nullable=False, index=True, comment="配置分类")
    config_type = Column(SQLEnum(ConfigType), nullable=False, default=ConfigType.STRING, comment="配置类型")
    config_scope = Column(SQLEnum(ConfigScope), nullable=False, default=ConfigScope.GLOBAL, comment="配置范围")
    
    # 配置元信息
    display_name = Column(String(100), nullable=False, comment="显示名称")
    description = Column(Text, comment="配置描述")
    default_value = Column(Text, comment="默认值")
    
    # 验证规则
    validation_rule = Column(JSON, comment="验证规则（JSON格式）")
    options = Column(JSON, comment="可选值列表（下拉选择用）")
    
    # 状态控制
    is_required = Column(Boolean, default=False, comment="是否必填")
    is_readonly = Column(Boolean, default=False, comment="是否只读")
    is_sensitive = Column(Boolean, default=False, comment="是否敏感信息")
    is_active = Column(Boolean, default=True, comment="是否启用")
    
    # 排序和分组
    sort_order = Column(Integer, default=0, comment="排序顺序")
    group_name = Column(String(50), comment="分组名称")
    
    # 审计字段
    last_modified_by = Column(String(50), comment="最后修改人")
    last_modified_at = Column(DateTime, default=datetime.utcnow, comment="最后修改时间")
    
    # 关联关系
    history_records = relationship("SystemConfigHistory", back_populates="config", cascade="all, delete-orphan")

    def __repr__(self):
        return f"<SystemConfig(key='{self.config_key}', category='{self.config_category}', value='{self.config_value[:50]}...')>"

    @property
    def parsed_value(self) -> Any:
        """根据配置类型解析配置值"""
        if not self.config_value:
            return None
            
        try:
            if self.config_type == ConfigType.BOOLEAN:
                return self.config_value.lower() in ('true', '1', 'yes', 'on')
            elif self.config_type == ConfigType.NUMBER:
                if '.' in self.config_value:
                    return float(self.config_value)
                return int(self.config_value)
            elif self.config_type == ConfigType.JSON:
                import json
                return json.loads(self.config_value)
            else:
                return self.config_value
        except (ValueError, TypeError):
            return self.default_value

    @property
    def is_encrypted(self) -> bool:
        """判断是否为加密字段"""
        return self.config_type == ConfigType.PASSWORD or self.is_sensitive

    def validate_value(self, value: Any) -> bool:
        """验证配置值是否符合规则"""
        if not self.validation_rule:
            return True
            
        try:
            import re
            rules = self.validation_rule
            
            # 必填验证
            if self.is_required and not value:
                return False
                
            # 类型验证
            if self.config_type == ConfigType.NUMBER:
                try:
                    float(value)
                except (ValueError, TypeError):
                    return False
                    
            # 正则验证
            if 'pattern' in rules:
                if not re.match(rules['pattern'], str(value)):
                    return False
                    
            # 长度验证
            if 'min_length' in rules and len(str(value)) < rules['min_length']:
                return False
            if 'max_length' in rules and len(str(value)) > rules['max_length']:
                return False
                
            # 数值范围验证
            if self.config_type == ConfigType.NUMBER:
                num_value = float(value)
                if 'min_value' in rules and num_value < rules['min_value']:
                    return False
                if 'max_value' in rules and num_value > rules['max_value']:
                    return False
                    
            return True
        except Exception:
            return False


class SystemConfigHistory(BaseModel):
    """
    系统配置变更历史模型
    
    记录配置的变更历史，支持审计和回滚
    """
    __tablename__ = "system_config_history"

    # 关联字段
    config_id = Column(Integer, nullable=False, index=True, comment="配置ID")
    config_key = Column(String(100), nullable=False, index=True, comment="配置键")
    
    # 变更信息
    old_value = Column(Text, comment="旧值")
    new_value = Column(Text, comment="新值")
    change_type = Column(String(20), nullable=False, comment="变更类型：create/update/delete")
    change_reason = Column(String(200), comment="变更原因")
    
    # 操作信息
    operated_by = Column(String(50), nullable=False, comment="操作人")
    operated_at = Column(DateTime, default=datetime.utcnow, nullable=False, comment="操作时间")
    client_ip = Column(String(45), comment="客户端IP")
    user_agent = Column(String(500), comment="用户代理")
    
    # 关联关系
    config = relationship("SystemConfig", back_populates="history_records")

    def __repr__(self):
        return f"<SystemConfigHistory(key='{self.config_key}', type='{self.change_type}', by='{self.operated_by}')>"


class SystemConfigTemplate(BaseModel):
    """
    系统配置模板模型
    
    预定义的配置模板，支持快速初始化系统配置
    """
    __tablename__ = "system_config_templates"

    # 模板信息
    template_name = Column(String(100), unique=True, nullable=False, comment="模板名称")
    template_description = Column(Text, comment="模板描述")
    template_version = Column(String(20), default="1.0", comment="模板版本")
    
    # 模板内容
    config_data = Column(JSON, nullable=False, comment="配置数据（JSON格式）")
    
    # 适用范围
    target_system = Column(String(50), comment="目标系统")
    target_version = Column(String(20), comment="目标版本")
    
    # 状态控制
    is_default = Column(Boolean, default=False, comment="是否默认模板")
    is_active = Column(Boolean, default=True, comment="是否启用")
    
    # 审计字段
    created_by = Column(String(50), nullable=False, comment="创建人")
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False, comment="创建时间")

    def __repr__(self):
        return f"<SystemConfigTemplate(name='{self.template_name}', version='{self.template_version}')>"


# 预定义的系统配置项
DEFAULT_SYSTEM_CONFIGS = [
    # 基础配置 - 系统基本信息
    {
        "config_key": "system.name",
        "config_value": "CRM旅游管理系统",
        "config_category": ConfigCategory.BASIC,
        "config_type": ConfigType.STRING,
        "display_name": "系统名称",
        "description": "显示在系统标题栏的名称",
        "is_required": True,
        "group_name": "基本信息",
        "sort_order": 1
    },
    {
        "config_key": "system.version",
        "config_value": "2.0.0",
        "config_category": ConfigCategory.BASIC,
        "config_type": ConfigType.STRING,
        "display_name": "系统版本",
        "description": "当前系统版本号",
        "is_readonly": True,
        "group_name": "基本信息",
        "sort_order": 2
    },
    {
        "config_key": "company.name",
        "config_value": "",
        "config_category": ConfigCategory.BASIC,
        "config_type": ConfigType.STRING,
        "display_name": "公司名称",
        "description": "使用系统的公司名称",
        "is_required": True,
        "group_name": "基本信息",
        "sort_order": 3
    },
    {
        "config_key": "company.address",
        "config_value": "",
        "config_category": ConfigCategory.BASIC,
        "config_type": ConfigType.STRING,
        "display_name": "公司地址",
        "description": "公司详细地址",
        "group_name": "基本信息",
        "sort_order": 4
    },
    {
        "config_key": "company.phone",
        "config_value": "",
        "config_category": ConfigCategory.BASIC,
        "config_type": ConfigType.STRING,
        "display_name": "联系电话",
        "description": "公司联系电话",
        "validation_rule": {"pattern": r"^1[3-9]\d{9}$"},
        "group_name": "基本信息",
        "sort_order": 5
    },
    {
        "config_key": "company.website",
        "config_value": "",
        "config_category": ConfigCategory.BASIC,
        "config_type": ConfigType.STRING,
        "display_name": "官网地址",
        "description": "公司官网URL",
        "validation_rule": {"pattern": r"^https?://"},
        "group_name": "基本信息",
        "sort_order": 6
    },
    
    # 业务配置 - 客户管理
    {
        "config_key": "customer.id_rule",
        "config_value": "CUST{YYYY}{MM}{DD}{###}",
        "config_category": ConfigCategory.BUSINESS,
        "config_type": ConfigType.STRING,
        "display_name": "客户编号规则",
        "description": "客户编号生成规则，支持日期和序号变量",
        "is_required": True,
        "group_name": "客户管理",
        "sort_order": 1
    },
    {
        "config_key": "customer.duplicate_check",
        "config_value": "true",
        "config_category": ConfigCategory.BUSINESS,
        "config_type": ConfigType.BOOLEAN,
        "display_name": "重复客户检测",
        "description": "是否启用重复客户检测功能",
        "group_name": "客户管理",
        "sort_order": 2
    },
    {
        "config_key": "customer.required_fields",
        "config_value": '["name", "phone", "gender", "age"]',
        "config_category": ConfigCategory.BUSINESS,
        "config_type": ConfigType.JSON,
        "display_name": "必填字段",
        "description": "客户信息中的必填字段列表",
        "group_name": "客户管理",
        "sort_order": 3
    },
    {
        "config_key": "customer.data_retention",
        "config_value": "365",
        "config_category": ConfigCategory.BUSINESS,
        "config_type": ConfigType.NUMBER,
        "display_name": "数据保留期限",
        "description": "客户数据保留天数",
        "validation_rule": {"min_value": 30, "max_value": 3650},
        "group_name": "客户管理",
        "sort_order": 4
    },
    
    # 业务配置 - 财务设置
    {
        "config_key": "finance.currency",
        "config_value": "CNY",
        "config_category": ConfigCategory.BUSINESS,
        "config_type": ConfigType.STRING,
        "display_name": "货币单位",
        "description": "系统使用的货币单位",
        "options": ["CNY", "USD", "EUR"],
        "group_name": "财务设置",
        "sort_order": 1
    },
    {
        "config_key": "finance.decimal_places",
        "config_value": "2",
        "config_category": ConfigCategory.BUSINESS,
        "config_type": ConfigType.NUMBER,
        "display_name": "小数位数",
        "description": "金额显示的小数位数",
        "validation_rule": {"min_value": 0, "max_value": 4},
        "group_name": "财务设置",
        "sort_order": 2
    },
    {
        "config_key": "finance.tax_rate",
        "config_value": "0.06",
        "config_category": ConfigCategory.BUSINESS,
        "config_type": ConfigType.NUMBER,
        "display_name": "默认税率",
        "description": "系统默认税率",
        "validation_rule": {"min_value": 0, "max_value": 1},
        "group_name": "财务设置",
        "sort_order": 3
    },
    
    # 系统参数 - 安全设置
    {
        "config_key": "security.password_complexity",
        "config_value": "true",
        "config_category": ConfigCategory.SYSTEM,
        "config_type": ConfigType.BOOLEAN,
        "display_name": "密码复杂度要求",
        "description": "是否要求密码必须包含大小写字母、数字和特殊字符",
        "group_name": "安全设置",
        "sort_order": 1
    },
    {
        "config_key": "security.password_expiry_days",
        "config_value": "90",
        "config_category": ConfigCategory.SYSTEM,
        "config_type": ConfigType.NUMBER,
        "display_name": "密码有效期",
        "description": "密码有效天数，0表示永不过期",
        "validation_rule": {"min_value": 0, "max_value": 365},
        "group_name": "安全设置",
        "sort_order": 2
    },
    {
        "config_key": "security.login_failure_limit",
        "config_value": "5",
        "config_category": ConfigCategory.SYSTEM,
        "config_type": ConfigType.NUMBER,
        "display_name": "登录失败锁定次数",
        "description": "连续登录失败多少次后锁定账户",
        "validation_rule": {"min_value": 3, "max_value": 10},
        "group_name": "安全设置",
        "sort_order": 3
    },
    {
        "config_key": "security.session_timeout",
        "config_value": "30",
        "config_category": ConfigCategory.SYSTEM,
        "config_type": ConfigType.NUMBER,
        "display_name": "会话超时时间",
        "description": "无操作自动登出时间（分钟）",
        "validation_rule": {"min_value": 5, "max_value": 480},
        "group_name": "安全设置",
        "sort_order": 4
    },
    
    # 系统参数 - 性能设置
    {
        "config_key": "performance.page_size",
        "config_value": "20",
        "config_category": ConfigCategory.SYSTEM,
        "config_type": ConfigType.NUMBER,
        "display_name": "分页大小",
        "description": "列表页面每页显示的记录数",
        "validation_rule": {"min_value": 10, "max_value": 100},
        "group_name": "性能设置",
        "sort_order": 1
    },
    {
        "config_key": "performance.cache_expiry",
        "config_value": "3600",
        "config_category": ConfigCategory.SYSTEM,
        "config_type": ConfigType.NUMBER,
        "display_name": "缓存有效期",
        "description": "缓存数据有效时间（秒）",
        "validation_rule": {"min_value": 60, "max_value": 86400},
        "group_name": "性能设置",
        "sort_order": 2
    },
    {
        "config_key": "performance.upload_limit",
        "config_value": "10",
        "config_category": ConfigCategory.SYSTEM,
        "config_type": ConfigType.NUMBER,
        "display_name": "文件上传大小限制",
        "description": "单个文件上传大小限制（MB）",
        "validation_rule": {"min_value": 1, "max_value": 100},
        "group_name": "性能设置",
        "sort_order": 3
    },
    
    # 系统参数 - 通知设置
    {
        "config_key": "notification.email_enabled",
        "config_value": "false",
        "config_category": ConfigCategory.SYSTEM,
        "config_type": ConfigType.BOOLEAN,
        "display_name": "启用邮件通知",
        "description": "是否启用邮件通知功能",
        "group_name": "通知设置",
        "sort_order": 1
    },
    {
        "config_key": "notification.smtp_server",
        "config_value": "",
        "config_category": ConfigCategory.SYSTEM,
        "config_type": ConfigType.STRING,
        "display_name": "SMTP服务器",
        "description": "邮件发送服务器地址",
        "group_name": "通知设置",
        "sort_order": 2
    },
    {
        "config_key": "notification.smtp_port",
        "config_value": "587",
        "config_category": ConfigCategory.SYSTEM,
        "config_type": ConfigType.NUMBER,
        "display_name": "SMTP端口",
        "description": "邮件服务器端口号",
        "validation_rule": {"min_value": 1, "max_value": 65535},
        "group_name": "通知设置",
        "sort_order": 3
    },
    {
        "config_key": "notification.smtp_username",
        "config_value": "",
        "config_category": ConfigCategory.SYSTEM,
        "config_type": ConfigType.STRING,
        "display_name": "SMTP用户名",
        "description": "邮件服务器登录用户名",
        "group_name": "通知设置",
        "sort_order": 4
    },
    {
        "config_key": "notification.smtp_password",
        "config_value": "",
        "config_category": ConfigCategory.SYSTEM,
        "config_type": ConfigType.PASSWORD,
        "display_name": "SMTP密码",
        "description": "邮件服务器登录密码",
        "is_sensitive": True,
        "group_name": "通知设置",
        "sort_order": 5
    },
    
    # 系统参数 - 数据备份设置
    {
        "config_key": "backup.storage_path",
        "config_value": "data/backups",
        "config_category": ConfigCategory.SYSTEM,
        "config_type": ConfigType.STRING,
        "display_name": "备份存储路径",
        "description": "数据备份文件的存储路径",
        "group_name": "备份设置",
        "sort_order": 1
    },
    {
        "config_key": "backup.compression",
        "config_value": "true",
        "config_category": ConfigCategory.SYSTEM,
        "config_type": ConfigType.BOOLEAN,
        "display_name": "启用备份压缩",
        "description": "是否压缩备份文件以节省空间",
        "group_name": "备份设置",
        "sort_order": 2
    },
    {
        "config_key": "backup.retention_days",
        "config_value": "30",
        "config_category": ConfigCategory.SYSTEM,
        "config_type": ConfigType.NUMBER,
        "display_name": "备份保留天数",
        "description": "自动清理多少天前的备份文件",
        "validation_rule": {"min_value": 7, "max_value": 365},
        "group_name": "备份设置",
        "sort_order": 3
    },
    {
        "config_key": "backup.auto_backup",
        "config_value": "false",
        "config_category": ConfigCategory.SYSTEM,
        "config_type": ConfigType.BOOLEAN,
        "display_name": "启用自动备份",
        "description": "是否启用定时自动备份",
        "group_name": "备份设置",
        "sort_order": 4
    }
]